<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
</body>
<script id="ColorVertexShader" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    attribute vec3 a_Normal;
    uniform float u_PointSize;
    uniform mat4 u_ModelM4;
    uniform mat4 u_PvM4;
    varying vec3 v_Normal;
    varying vec3 v_Position;
    void main(){
        gl_Position = u_PvM4 * u_ModelM4 * a_Position;
        gl_PointSize = u_PointSize;
        v_Normal = a_Normal;
        v_Position = vec3(a_Position);
    }
</script>
<script id="ColorFragmentShader" type="x-shader/x-fragment">
    precision mediump float;
    uniform vec3 u_Kd;
    uniform vec3 u_Ks;
    uniform vec3 u_Eye;
    uniform vec3 u_LightDir;
    varying vec3 v_Normal;
    varying vec3 v_Position;
    void main(){
        vec3 eyeDir = normalize(u_Eye - v_Position);
        vec3 el = eyeDir + u_LightDir;
        vec3 h = el / length(el);

        vec3 Ls = u_Ks * pow(max(0.0, dot(v_Normal, h)), 128.0);
        vec3 Ld = u_Kd * max(0.0, dot(v_Normal,u_LightDir));

        //Blinn-Phong反射
        vec3 l = Ls + Ld;

        gl_FragColor = vec4(l, 1.0);
    }
</script>
<script type="module">
    import { Matrix4, Vector3, Color, SphereGeometry, PerspectiveCamera, } from '../js/three.module.js';
    import { CreateProgram, imgPromise } from '../js/Utils.js';
    import lib from '../js/ThreeLib.js';
    import CameraController from '../js/CameraController.js'
    import Poly from '../js/Poly4.js'
    import Control from '../js/Control.js'

    import Geo from '../js/Poly2/Geo.js'
    import Mat from '../js/Poly2/Mat.js'
    import Obj3D from '../js/Poly2/Obj3D.js'
    import Scene from '../js/Poly2/Scene.js'



    //#region gl
    const canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight - 4;

    const gl = canvas.getContext("webgl", { antialias: true, });

    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.enable(gl.DEPTH_TEST);
    // gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);//去图片描边
    //#endregion


    const scene = new Scene({ gl: gl });
    scene.regProgram('color', {
        program: CreateProgram(gl,
            document.querySelector('#ColorVertexShader').innerText,
            document.querySelector('#ColorFragmentShader').innerText),
        attribs: ['a_Position', 'a_Normal'],
        uniforms: ['u_PvM4', 'u_ModelM4', 'u_PointSize',
            'u_LightDir', 'u_Kd', 'u_Ks', 'u_Eye']
    })


    const pvM4 = new Matrix4();
    const modelM4 = new Matrix4();

    const camera = new PerspectiveCamera(45, canvas.width / canvas.height, 1, 20);
    const cameraController = new CameraController({
        canvas,
        camera,
        pvMatrix: pvM4
    });



    const sphere = new SphereGeometry(0.5, 100, 100);

    const { array: nodeArr } = sphere.getAttribute('position');
    const { array: normals } = sphere.getAttribute('normal');
    const { array: elements } = sphere.index;

    const LightDir = new Vector3(1, 1, 1).normalize();//光线方向
    const Kd = [1, 1, 1];//漫反射系数
    const Ks = [1, 0, 0];//镜面反射系数



    let obj01 = new Obj3D({
        geo: new Geo({
            data: {
                'a_Position': { size: 3, array: nodeArr },
                'a_Normal': { size: 3, array: normals },
            },
            element: {
                array: elements
            }
        }),
        mat: new Mat({
            program: 'color',
            mode: ['TRIANGLES'],
            data: {
                'u_PvM4': { type: 'uniformMatrix4fv', value: pvM4.elements },
                'u_ModelM4': { type: 'uniformMatrix4fv', value: modelM4.elements },
                'u_PointSize': { type: 'uniform1f', value: 30 },
                'u_Kd': { type: 'uniform3fv', value: Kd },
                'u_Ks': { type: 'uniform3fv', value: Ks },
                'u_LightDir': { type: 'uniform3fv', value: [...LightDir] },
                'u_Eye': { type: 'uniform3fv', value: [...cameraController.eye] },
            },
        }),
    });
    scene.add(obj01);
    draw();

    (function ani() {
        draw();
        requestAnimationFrame(ani);
    })();

    function draw() {
        scene.setUniform('u_Eye', { value: [...cameraController.eye] });
        scene.draw();
    }
</script>

</html>